package com.ruoyi.common.core.domain;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.common.utils.StringUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 操作消息提醒
 *
 * @author ruoyi
 */
public class AjaxResult extends HashMap<String, Object> {
    private static final long serialVersionUID = 1L;

    /**
     * 状态码
     */
    public static final String CODE_TAG = "code";

    /**
     * 返回内容
     */
    public static final String MSG_TAG = "msg";

    /**
     * 数据对象
     */
    public static final String DATA_TAG = "data";

    /**
     * 时间戳
     */
    public static final String TIMESTAMP_TAG = "timestamp";

    /**
     * 状态类型
     */
    public enum Type {
        /**
         * 成功
         */
        SUCCESS(0),
        /**
         * 警告
         */
        WARN(301),
        /**
         * 错误
         */
        ERROR(500);
        private final int value;

        Type(int value) {
            this.value = value;
        }

        public int value() {
            return this.value;
        }
    }

    /**
     * 初始化一个新创建的 AjaxResult 对象，使其表示一个空消息。
     */
    public AjaxResult() {
    }

    /**
     * 初始化一个新创建的 AjaxResult 对象
     *
     * @param type 状态类型
     * @param msg  返回内容
     */
    public AjaxResult(Type type, String msg) {
        super.put(CODE_TAG, type.value);
        super.put(MSG_TAG, msg);
    }

    /**
     * 初始化一个新创建的 AjaxResult 对象
     *
     * @param type 状态类型
     * @param msg  返回内容
     * @param data 数据对象
     */
    public AjaxResult(Type type, String msg, Object data) {
        super.put(CODE_TAG, type.value);
        super.put(MSG_TAG, msg);
        if (StringUtils.isNotNull(data)) {
            super.put(DATA_TAG, data);
        }
    }

    /**
     * 返回成功消息
     *
     * @return 成功消息
     */
    public static AjaxResult success() {
        return AjaxResult.success("操作成功");
    }

    /**
     * 返回成功数据
     *
     * @return 成功消息
     */
    public static AjaxResult success(Object data) {
        return AjaxResult.success("操作成功", data);
    }

    /**
     * 返回成功消息
     *
     * @param msg 返回内容
     * @return 成功消息
     */
    public static AjaxResult success(String msg) {
        return AjaxResult.success(msg, null);
    }

    /**
     * 返回成功消息
     *
     * @param msg  返回内容
     * @param data 数据对象
     * @return 成功消息
     */
    public static AjaxResult success(String msg, Object data) {
        return new AjaxResult(Type.SUCCESS, msg, data);
    }

    /**
     * 返回警告消息
     *
     * @param msg 返回内容
     * @return 警告消息
     */
    public static AjaxResult warn(String msg) {
        return AjaxResult.warn(msg, null);
    }

    /**
     * 返回警告消息
     *
     * @param msg  返回内容
     * @param data 数据对象
     * @return 警告消息
     */
    public static AjaxResult warn(String msg, Object data) {
        return new AjaxResult(Type.WARN, msg, data);
    }

    /**
     * 返回错误消息
     *
     * @return
     */
    public static AjaxResult error() {
        return AjaxResult.error("操作失败");
    }

    /**
     * 返回错误消息
     *
     * @param msg 返回内容
     * @return 警告消息
     */
    public static AjaxResult error(String msg) {
        return AjaxResult.error(msg, null);
    }

    /**
     * 返回错误消息
     *
     * @param msg  返回内容
     * @param data 数据对象
     * @return 警告消息
     */
    public static AjaxResult error(String msg, Object data) {
        return new AjaxResult(Type.ERROR, msg, data);
    }

    private AjaxResult(Map<String, Object> propertiesMap) {
        this.putAll(propertiesMap);
    }

    public static RetBuild ok() {
        return getBuild().ok();
    }

    public static RetBuild ok(String msg) {
        return getBuild().ok(msg);
    }

    public static RetBuild fail() {
        return getBuild().fail();
    }

    public static RetBuild fail(String msg) {
        return getBuild().fail(msg);
    }

    public static RetBuild getBuild() {
        return new RetBuild();
    }

    public static class RetBuild {

        private static final String RESULT_TAG = "result";

        private static final String LIST_TAG = "list";

        private Map<String, Object> propertiesMap = new HashMap<String, Object>();

        private Map<String, Object> dataMap = new HashMap<>();

        public RetBuild ok() {
            propertiesMap.put(CODE_TAG, Type.SUCCESS.value);
            propertiesMap.put(MSG_TAG, "操作成功");
            return this;
        }

        public RetBuild ok(String msg) {
            propertiesMap.put(CODE_TAG, Type.SUCCESS.value);
            propertiesMap.put(MSG_TAG, msg);
            return this;
        }

        public RetBuild code(int code) {
            propertiesMap.put(CODE_TAG, code);
            return this;
        }

        public RetBuild fail() {
            propertiesMap.put(CODE_TAG, Type.ERROR.value);
            propertiesMap.put(MSG_TAG, "操作失败");
            return this;
        }

        public RetBuild fail(String msg) {
            propertiesMap.put(CODE_TAG, Type.ERROR.value);
            propertiesMap.put(MSG_TAG, msg);
            return this;
        }


        public RetBuild result(boolean result) {
            propertiesMap.put(RESULT_TAG, result);
            return this;
        }

        public RetBuild data(Object data) {
            propertiesMap.put(DATA_TAG, data);
            return this;
        }

        public RetBuild list(Collection<?> collection) {
            propertiesMap.put(LIST_TAG, collection);
            return this;
        }

        public RetBuild page(IPage<?> page, List<?> list) {
            propertiesMap.put("total", page.getTotal());
            propertiesMap.put("rows", list);
            propertiesMap.put("pages", page.getPages());
            propertiesMap.put("current", page.getCurrent());
            propertiesMap.put("size", page.getSize());
            return this;
        }

        public RetBuild page(IPage<?> page) {
            propertiesMap.put("total", page.getTotal());
            propertiesMap.put("rows", page.getRecords());
            propertiesMap.put("pages", page.getPages());
            propertiesMap.put("current", page.getCurrent());
            propertiesMap.put("size", page.getSize());
            return this;
        }

        public RetBuild proPut(String key, Object value) {
            propertiesMap.put(key, value);
            return this;
        }

        public RetBuild put(String key, Object value) {
            dataMap.put(key, value);
            return this;
        }

        public RetBuild put(Map<String, Object> map) {
            dataMap.putAll(map);
            return this;
        }

        public AjaxResult build() {
            if (StringUtils.isNotEmpty(dataMap)) {
                propertiesMap.put(DATA_TAG, dataMap);
            }
            propertiesMap.put(TIMESTAMP_TAG, System.currentTimeMillis());
            return new AjaxResult(propertiesMap);
        }
    }

}
